package com.night.icm.service.base.service;

import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.night.icm.common.exception.NoSuchDataException;
import com.night.icm.common.jpa.PageHelper;
import com.night.icm.common.service.PageDataUtil;
import com.night.icm.common.utils.PageDataDTO;
import com.night.icm.common.utils.SimpleDataDTO;
import com.night.icm.model.base.AcademyDTO;
import com.night.icm.persistence.base.entity.Academy;
import com.night.icm.persistence.base.repository.AcademyRepository;
import com.night.icm.service.base.mapper.AcademyMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * AcademyServiceImpl
 *
 * @author Liao ZhiYong
 * @date 2020/1/5
 */
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class AcademyServiceImpl implements AcademyService {

    private final AcademyMapper academyMapper;
    private final AcademyRepository academyRepository;

    @Autowired
    public AcademyServiceImpl(AcademyMapper academyMapper, AcademyRepository academyRepository) {
        this.academyMapper = academyMapper;
        this.academyRepository = academyRepository;
    }

    /**
     * 新建学院
     *
     * @param academyDTO 学院信息
     * @return 新增的学院信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AcademyDTO create(AcademyDTO academyDTO) {
        Academy academy = this.academyMapper.toEntity(academyDTO);
        Academy save = this.academyRepository.save(academy);
        return this.academyMapper.toDTO(save);
    }

    /**
     * 分页查找学院信息
     *
     * @param page 页号，从0开始
     * @param size 每页纪录条数
     * @param sort 排序字段, 例如：字段1,asc,字段2,desc
     * @param name 学院名称
     * @param code 学院编号
     * @return 学院信息
     */
    @Override
    public PageDataDTO<AcademyDTO> findOnePage(int page, int size, String sort, String name, String code) {
        PredicateBuilder<Academy> pb = Specifications.<Academy>and()
                .like(StringUtils.isNotBlank(name), "name", "%" + name + "%")
                .like(StringUtils.isNotBlank(code), "code", "%" + code + "%");
        Page<Academy> entities = this.academyRepository.findAll(pb.build(), PageHelper.generatePageRequest(page, size, sort));
        List<AcademyDTO> dtos = this.academyMapper.toList(entities.getContent());
        return PageDataUtil.toPageData(entities, dtos);
    }

    /**
     * 根据id删除学院信息
     *
     * @param id 学院id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(String id) {
        this.academyRepository.deleteById(Long.valueOf(id));
    }

    /**
     * 更新学院信息
     *
     * @param id         学院id
     * @param academyDTO 学院信息
     * @return 更新后学院信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AcademyDTO update(String id, AcademyDTO academyDTO) {
        Academy academy = this.getOne(id);
        this.academyMapper.updateEntity(academyDTO, academy);
        this.academyRepository.save(academy);
        return this.academyMapper.toDTO(academy);
    }

    /**
     * 通过id查找学院
     *
     * @param id 学院id
     * @param isGetProfession 是否获取专业
     * @return 学院信息
     */
    @Override
    public AcademyDTO findById(String id, Boolean isGetProfession) {
        Academy academy = this.getOne(id);
        return isGetProfession ? this.academyMapper.toDTO(academy) : this.academyMapper.toDtoByPage(academy);
    }

    /**
     * 根据id获取学院
     *
     * @param id 学院id
     * @return 学院
     */
    private Academy getOne(String id) {
        Optional<Academy> academyOptional = this.academyRepository.findById(Long.valueOf(id));
        if (!academyOptional.isPresent()) {
            throw new NoSuchDataException(id);
        }
        return academyOptional.get();
    }
    /**
     * 查找所有学院信息
     *
     * @return 学院信息
     */
    @Override
    public List<AcademyDTO> findAll() {
        List<Academy> entitys = this.academyRepository.findAll();
        return this.academyMapper.toList(entitys);
    }

    /**
     * 查找所有学院信息，并排序
     *
     * @param param   排序参数
     * @param pattern 排序模式: asc/desc
     * @return 学院信息
     */
    @Override
    public List<AcademyDTO> findAllBySort(String param, String pattern) {
        String keyType = "asc";
        Sort sort;
        if (keyType.equals(pattern)) {
            sort = new Sort(Sort.Direction.ASC, param);
        } else {
            sort = new Sort(Sort.Direction.DESC, param);
        }
        List<Academy> all = this.academyRepository.findAll(sort);
        return this.academyMapper.toList(all);
    }

    /**
     * 检查学院编码是否存在
     *
     * @param code 学院编码
     * @return 是或否
     */
    @Override
    public SimpleDataDTO<Boolean> checkoutCodeIsExist(String code) {
        SimpleDataDTO<Boolean> simpleDataDTO = new SimpleDataDTO<>();
        Long academyId = this.academyRepository.findAcademyByCode(code);
        simpleDataDTO.setData(academyId != null);
        return simpleDataDTO;
    }

    /**
     * 统计学院数量
     *
     * @return 学院数量
     */
    @Override
    public Long countAcademy() {
        return this.academyRepository.count();
    }
}